Repository navigation
Conversation
Adds a 4.23.0 to 24.0.0 upgrade path (squashed from sb/upgradepath-424: engine-schema: upgrade path for 24.0.0, fix CS version, fix upgrade unit tests for cutover, fix imports).
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
711eb46 to
219f9cb
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #14166 +/- ##
============================================
Coverage 20.66% 20.67%
+ Complexity 21723 20716 -1007
============================================
Files 6492 6049 -443
Lines 590728 547505 -43223
Branches 72448 73132 +684
============================================
- Hits 122054 113174 -8880
+ Misses 455404 421071 -34333
+ Partials 13270 13260 -10
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
🔴 Test Coverage Grade:
|
| Metric | Value |
|---|---|
| Line coverage | 25.55% |
| Branch coverage | 20.71% |
Grade Scale
| Grade | Line Coverage | Meaning |
|---|---|---|
| 🟢 A | ≥ 80% | Excellent - this code sleeps well at night 😴 |
| 🟡 B | 60-79% | Good - almost there, don't stop now 😉 |
| 🟠 C | 40-59% | Acceptable - your code is wearing a seatbelt, but no airbags 😬 |
| 🔴 D | 20-39% | Marginal - boldly shipping where no test has gone before 🖖 |
| ⛔ F | < 20% | Failing - tests? what tests? 🔥 |
Branch coverage is shown as a secondary signal. Grade is determined by line coverage.
View full Actions run
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
The (nic_id, network_id) unique key rejected re-associating a network after a prior disassociate, since the old row's uniqueness survives as a soft-deleted (removed) row. Switch to a plain index so re-association after disassociation works, relying on application-level checks (not the DB) to reject a true duplicate live association.
…fallback Trunk NIC VLAN membership is delivered by reusing the existing guest bridge with vlan_filtering=1: the primary VLAN gets native/untagged membership, associated VLANs get tagged-only membership, via libvirt's <vlan trunk='yes'> element where supported, or manual `bridge vlan add` on older libvirt. Adds a live membership update path (UpdateNicVlanMembershipCommand/Answer + its KVM wrapper) so an association change on a running VM is pushed to the host without a restart, and a non-blocking diagnostic warning when the physical uplink is missing a VLAN a trunk NIC needs (CloudStack no longer manages the uplink's own VLAN membership - that is the operator's responsibility).
- New UsageEventUtils.publishNicNetworkOfferingUsageEvents() emits one usage event per network a nic bills against (primary + any trunk associations), replacing the old single-event publishUsageEvent at every NIC-billing call site - Ordinary non-trunk nics still produce exactly one event, unchanged - New nullable usage_network_offering.network_id column disambiguates rows when a trunk nic's networks share one network offering - Backfills network_id on a nic's own still-open usage row(s) the moment it first converts to a trunk nic; historic rows otherwise left alone
- New NicNetworkMapResponse + trunked/associatednetworks fields on NicResponse - Populated in listNics, listVirtualMachines, and the associate/disassociate/change-primary command responses - Trunk status derived from nic_network_map rows rather than a new column on the wide UserVmJoinVO view
- ASSOCIATED_NETWORKS/TRUNKED, needed by the previous commit's NicResponse fields
Core capability: - New associateNetworkToNic/disassociateNetworkFromNic/changeNicPrimaryNetwork admin APIs and associateNetworksToNic (programmatic, used by deploy) - A nic keeps one primary network plus any number of additional associated networks (nic_network_map), delivered as a VLAN trunk - changeNicPrimaryNetwork only allowed while the Instance is stopped - Rejects associating a network already reachable via another of the VM's nics, or with an overlapping CIDR to an existing association - Disassociating a network is blocked while an active PF/Static NAT/LB rule targets its allocated IP PF/Static NAT/LB support for associated networks: - NetworkModel.getNicAndIpInNetwork resolves a nic/guest-ip pair via the nic's primary match or a trunk association, reused by RulesManagerImpl and LoadBalancingRulesManagerImpl so these rules can target a trunk nic's associated networks, not just its primary Deployment planning: - Hosts without VLAN filtering enabled are excluded up front for any VM with a multi-VLAN trunk nic, with a reactive fallback exclusion during start as a backstop - Removing a nic cleans up any trunk associations it held as primary; deleting a network is blocked while still associated as a secondary Metadata: - A trunk nic's associated-network VLAN tags are exposed to the guest via the metadata service (nic-vlan-mapping file), gated by a new account-scoped config key, off by default
- EVENT_NIC_NETWORK_ASSOCIATE/DISASSOCIATE/PRIMARY_NETWORK_CHANGE, needed by the previous commit's @actionevent annotations
- New nicnetworkslist deploy param (nicnetworkslist[N].networkids, first id primary) lets a VM be deployed with trunk nics directly, mutually exclusive with networkids/iptonetworklist/vApp nicnetworklist - Also carries per-entry ip4address/ip6address for the primary and ip4addresses/ip6addresses (comma-separated) for its associated networks - a network with no requested IP auto-allocates - VNF: rejects a management-device nic from being requested as a trunk, both at deploy time and via the live associate API
- checkNoActiveRulesOnAssociation used findByIpAndNetworkId, which matches on a public IP's own address - the association's IP is a guest IP, so this never matched and the guard silently let disassociation through even with an active static NAT rule - Use findByAssociatedVmIdAndVmIp instead, which matches the actual static NAT target mapping
- validateVnfApplianceTrunkNics only ran at deploy time (nicnetworkslist) - the live associateNetworkToNic/associateNetworksToNic path had no equivalent check, so a VNF's management nic could be trunked after deploy - New single-nic validateVnfApplianceTrunkNic, called from associateNetworksInternal so both entry points are covered - No-op for any non-VNF template
- changeNicPrimaryNetwork updated networkId and the IPv4/IPv6 address but left gateway, netmask, broadcast/isolation uri, and IPv6 gateway/cidr pointing at the old primary network - wrong indefinitely, since nothing else ever recomputes them - New applyNetworkAddressingToNic refreshes them from the new primary network, mirroring the field derivation used when a nic is first created
- disassociateNetworkFromNic now clears nics.multi_network once nic_network_map has no remaining rows for that nic - Without this, listNics/listVirtualMachines kept reporting trunked=true and the deployment planner kept restricting the VM to VLAN-filtering- capable hosts even after all associations were removed
- New CommandSetupHelper.createDhcpEntryCommand overload takes addressing explicitly instead of reading it off a NicVO, since a nic's own DB row only ever carries its primary network's IP/gateway - NetworkServiceImpl sends the entry directly to the associated network's router(s) on live associate/disassociate, bypassing the DhcpServiceProvider pipeline (which re-resolves the nic from the DB and so can never see anything but the primary IP) - UserVmManagerImpl.finalizeStart converges a nic's associated-network DHCP entries with its current nic_network_map rows on every VM start, covering associations made while the VM was stopped and cleaning up entries for associations removed while stopped - New NicNetworkMapDao.listRemovedByNicId to support that cleanup
|
@Pearl1594 a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19815 |
|
@blueorangutan test |
|
@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests |
|
[SF] Trillian test result (tid-17318)
|
|
@blueorangutan test |
|
@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests |
… and live nic add, using the network's VLAN when the nic has none
|
@blueorangutan package |
|
@Pearl1594 a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✖️ el8 ✖️ el9 ✔️ debian ✔️ suse15. SL-JID 19856 |
|
@blueorangutan package |
|
@Pearl1594 a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19858 |
|
[SF] Trillian test result (tid-17333)
|
…VLAN 1 nics as needing a legacy host, including in host planning
|
@blueorangutan package |
|
@RosiKyu a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress. |
|
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19861 |
|
@blueorangutan test |
|
@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests |
|
[SF] Trillian test result (tid-17353)
|
|
@blueorangutan test |
|
@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests |
|
[SF] Trillian test result (tid-17369)
|
There was a problem hiding this comment.
LGTM, based on manual QA of the head of this PR (d644d6e).
Test environment
- KVM hosts in all three host profiles the feature supports:
- Legacy: no VLAN filtering.
- VLAN filtering with libvirt older than 11: Oracle Linux 9 with libvirt 9.0 and 10.10.
- VLAN filtering with libvirt 11: Oracle Linux 9 with libvirt 11.10, and Debian 13 with libvirt 11.3.
- An Advanced zone and a Security Group zone. Isolated, Shared, L2, VPC tier and untagged networks. Two management servers for the cross-server cases.
- Every round was redone on each new head; the last full round was on d644d6e.
Results
- The full test plan of 196 test cases was run, plus additional exploratory, failure injection and regression scenarios.
- Issues found during testing were addressed in this PR and re-verified on the final build.
Areas tested
- Host profile detection and conversion: VLAN filtering, STP and libvirt version detection, and host details, including readiness taken from the Guest traffic label when it differs from guest.network.device. Converting a Legacy host to VLAN filtering, including with VMs running, and a libvirt 9 to 11 upgrade done through maintenance.
- Associate, disassociate and changeNicPrimaryNetwork: on running and stopped VMs, on Isolated, Shared, VPC tier and dual-stack networks, and up to 50 associations and VLAN 4094.
- Checked after each change: IP allocation and release, router DHCP entries, the nic-vlan-mapping file, events and usage.
- Rollback when a later network in a multi-network call fails, including the host side on libvirt older than 11.
- Associating a network that was never implemented starts its router.
- Two trunk NICs on one VPC tier router keep both DHCP entries.
- With the association network's router stopped, or destroyed and recreated, the DHCP entries are rebuilt.
- Redundant routers: entries reach both routers and survive failover.
- Access checks: run against the VM owner, and an access error comes before "already associated".
- listNics and listVirtualMachines on an association network: scoping, filters and paging.
- Deploy with nicnetworkslist and assignVirtualMachine: Validation and negative paths: invalid combinations, other accounts' networks, domain admin limits, gateway and duplicate IPs, and the same network twice in one call. A rejected call leaves nothing behind.
- On the wire: tap VLAN membership on each host profile, native and manual paths. No VLAN 1 leak, untagged frames, and VLAN hopping attempts with double tags and VLAN 1.
- Guest side: DHCP and metadata on associated VLANs, and port forwarding, static NAT, load balancing and egress rules on associated addresses.
- Network lifecycle guards: delete, network GC, CIDR change, offering change, migrateNetwork and migrateVpc.
- Live migration across profiles:
- Legacy, manual and native in each direction: the supported directions work and the others are refused with a clear message.
- findHostsForMigration reasons and the UI tooltip.
- HA, host maintenance, host reboot, and agent and libvirtd restarts.
- VLAN 1 networks on converted hosts:
- Trunk NIC plus VLAN 1 refused on every path.
- Plain VLAN 1 VMs placed on Legacy hosts, and router, SSVM and CPVM Public NICs on VLAN 1.
- Maintenance with and without a Legacy host available.
- SSVM and CPVM with Management and Storage NICs on VLAN 1, run on converted hosts:
- The Storage NIC on VLAN 1, carried on the guest uplink, gets its own VLAN 1 bridge. Secondary storage NFS mounts through it.
- Its frames leave the host tagged VLAN 1, with nothing untagged and nothing on the guest bridge.
- The SSVM live migrates between native, manual and Legacy hosts with storage working after each move.
- The Management NIC is plugged untagged into the management bridge, as on stock KVM, and the agents connect.
- Concurrency: parallel associate calls, associate against network delete, and calls spread across two management servers.
- VM operations on trunk VMs: VM snapshots with and without memory, NIC link down and up, suspend and resume, scale, restore, destroy and recover, unmanage (refused), and projects.
- Feature switched off in the zone: existing trunk VMs keep working and new trunk operations are refused.
- Security Group zone: trunk NICs are refused where security groups apply.
- UI: the association dialogs, NIC listings, address pickers for rules, and the migration wizard.
- Regression: ordinary VMs, routers, redundant VPC failover and system VMs on Legacy and converted hosts, and usage jobs.
Not tested
- The out of scope items from the documentation: backup and restore, VXLAN, and two untagged networks on one host.
Minor, left as is
- A deploy or start with the hostid of a host that cannot take the VM gives the generic "No destination found". The same happens for a trunk VM with the hostid of a Legacy host.
- The assignVirtualMachine refusal for a trunk NIC plus a VLAN 1 network shows a generic message. The reason is in the management server log.
Unrelated issues seen during testing
- A VM start fails with an NPE in deployInVmLastHost when the VM's last host has been removed. This is on main since #12711, and stock 4.22.1.1 starts the same VM.
- The router's dnsmasq 2.90 crashes (SIGSEGV) on reload after a DHCP entry change. This also happens on routers without associations and on stock 4.22.1.1, and it is fixed upstream in dnsmasq 2.91.
- deleteManagementNetworkIpRange fails with an NPE ("Cannot invoke "String.equals(Object)" because "vlan" is null") when vlan is given as
1oruntagged. It works withvlan://1. This PR does not change that code.
Code coverage (Codecov at d644d6e)
- Patch coverage is 58.60% (936 changed lines not covered by unit tests). Project coverage is 20.67%.
- Coverage of the main changed files:
- NetworkServiceImpl: 73.26%
- BridgeVifDriver: 67.45%
- BaseDeployVMCmd: 66.96%
- UserVmManagerImpl: 60.79%
- NetworkOrchestrator: 40.17%
- VirtualMachineManagerImpl: 28.57%
- NicNetworkMapDaoImpl: 24.44%
- LibvirtComputingResource: 14.28%
- The associate, disassociate, deploy, migration and host profile paths in these files were all exercised by the manual tests above.
Latest smoke test run
- The last smoke run had 3 failures:
- test_router_dhcphosts
- test_01_RVR_Network_FW_PF_SSH_default_routes_egress_true
- test_02_isolate_network_FW_PF_default_routes_egress_false
- All three fail on traffic from a guest to the internet:
- Two get 2 of 3 replies to
ping -c 3 8.8.8.8, and the tests require 0% loss. - One runs
curl -m 1right after the egress rule was applied on the router, and it timed out.
- Two get 2 of 3 replies to
- The hosts in that run report
vlan.filtering.enabledfalse, so the new VLAN filtering paths were not in use. - The same flows were rerun by hand on the PR build:
- Add the egress rule for TCP 80, then run
curl -m 1at once from guests on a native and a manual host, with the router on a Legacy host: 20 of 20 got200 OK. - The router's dhcphosts file lists both VMs with the right MAC and IP.
ping -c 3 8.8.8.8, 15 times per guest: one guest had two runs with 2 of 3 replies. The bare hosts, with no VM or router in the path, lost a reply at the same rate.
- Add the egress rule for TCP 80, then run
- So the failures match packet loss on the path to the internet. The flow was not run on a stock build. The log is attached.
|
@blueorangutan test |
|
@Pearl1594 a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests |
|
[SF] Trillian Build Failed (tid-17472) |




Description
This PR adds support for multi-vlan trunk NICs
doc PR: apache/cloudstack-documentation#689
https://cwiki.apache.org/confluence/spaces/CLOUDSTACK/pages/451972290/Multi+VLAN+trunk+NICs+support+in+KVM
Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Screenshots (if appropriate):
How Has This Been Tested?
Core trunk mechanism (KVM delivery)
Association lifecycle
Cross-VPC trunk associations
VM deploy and VNF
Network type coverage
DHCP correctness
Usage and billing
Migration
AssignVirtualMachine to another account
UI
How did you try to break this feature and the system with this change?